function [prinp, intp, bal, p] = amortize(rate, nper, pv, fv, due)
%AMORTIZE Amortization.
%   AMORTIZE returns the principal and interest portions of a loan paid by a
%   periodic payment and computes the remaining balance of the original loan
%   amount and the periodic payment.
%
%   [PRINP, INTP, BAL, P] = amortize(RATE, NPER, PV)
%   [PRINP, INTP, BAL, P] = amortize(RATE, NPER, PV, FV, DUE)
%
%   Optional Inputs: FV, DUE
%
%   Inputs:
%    RATE - Scalar value for the periodic interest rate charged.
%
%    NPER - Scalar value for the number of payment periods.
%
%      PV - Scalar value for the present value of the loan.
%
%   Optional Inputs:
%      FV - Scalar value for the future value of the loan. Default FV = 0.
%
%     DUE - Scalar value that specifies whether the payments are made at the
%           beginning (due = 1) or end (Default: due = 0) of the period.
%
%   prinp is a vector of the principal paid in each period, intp is a vector
%   of the interest paid in each period, bal is the remaining balance of the
%   loan in each payment period, and p is the periodic payment calculated by
%   the payment function.
%
%
%
%   Outputs:
%   PRINP - 1 x NPER vector of the principal paid in each period.
%
%    INTP - 1 x NPER vector of the interest paid in each period.
%
%     BAL - 1 x NPER vector of the remaining balance of the loan in each
%           payment period.
%
%       P - Scalar payment per period.
%
%   Example:
%      Find the values for a $500 loan paid in six installments at an annual
%      interest rate of 9%:
%
%      [prinp, intp, bal, p] = amortize(0.09/6, 6, 500)
%
%       returns
%
%       prinp = [80.26 81.47 82.69 83.93 85.19 86.47]
%       intp  = [7.50 6.30 5.07 3.83 2.57 1.30]
%       bal   = [419.74 338.27 255.58 171.65 86.47 0.00]
%       p     = 87.76
%
%   See also ANNUTERM, ANNURATE, PAYADV, PAYODD, PAYPER.

%       Copyright 1995-2006 The MathWorks, Inc.
%       $Revision: 1.7.2.3 $   $Date: 2008/08/18 16:49:23 $

% Input validation
if nargin < 5 || isempty(due)
    due = 0; % Default time of payment
end
if nargin < 4 || isempty(fv)
    fv = 0; % Default future value
end
if nargin < 3
    error('finance:amortize:tooFewInputs', ...
        'Too few inputs.')
end

if numel(rate) > 1 || isempty(rate)
    error('finance:amortize:invalidRate', ...
        'RATE must be scalar value.')
end

if rate < 0
    error('finance:amortize:invalidRate', ...
        'RATE must be >= 0.')
end

if numel(nper) > 1 || isempty(nper)
    error('finance:amortize:invalidPeriod', ...
        'PERIOD must be scalar value.')
end

if numel(pv) > 1 || isempty(pv)
    error('finance:amortize:invalidPV', ...
        'PV must be scalar value.')
end

if numel(fv) > 1
    error('finance:amortize:invalidFV', ...
        'FV must be scalar value.')
end

if numel(due) > 1
    error('finance:amortize:invalidDue', ...
        'DUE must be scalar value.')
end

p = payper(rate, nper, pv, fv, due);                % Calculate monthly payment

% Function only takes one set of scalar inputs at a time
% due to possible different 1:nper lengths and fact that outputs are vectors.
c = 1+rate;
n = 0:nper;
if due == 0                                         % End of month payment
    AllBal = pv*c.^n-p*(1-c.^n)/(1-c);                % Compute remaining balance
    intp = abs(AllBal(1:end-1)*rate);                 % Compute interest paid
    bal = AllBal(2:end);

else                                                % Beginning of month payment
    AllBal = pv*c.^n-p*(1-c.^(n+1))/(1-c);            % Compute remaining balance
    intp = [0 abs(AllBal(1:end-2)*rate)];             % Compute interest paid
    bal = AllBal(1:end-1);
end
prinp = abs(p)-intp;                                % Compute principal paid


% {EOF]
